<?php
namespace app\designer\controller;

use app\admin\library\AdminController;
use cubox\Cubox;
use cubox\Cache;
use cubox\Data;

class Database extends AdminController{

    public function __construct()
    {
        parent::__construct();
        $this->power('designer');
    }

    private function getApp(){
        $app = $this->post('app',$this->check('应用')->type('stirng')->required());
        if (!$this->app->design($app)){
            throw new \Exception('该应用不支持设计');
        }
        return $app;
    }

    public function onModelList(){
        
        $name = $this->getApp();

        $project = $this->app->project($name);
        
        $table =  $project->model;
        
        $list  = [];
        if ($table){
            foreach ($table as $key => $value) {
                $item = $value;
                $item['name'] = $key;
                $list[] = $item;
            }
        }
        
        return $list;
    }


    public function onTableList(){
        
        $name  =  $this->post('name',$this->check()->required());
        $db = Cubox::app($this->app->project($this->getApp())->toArray())->db($name);

        $config = $db->getConfig();

        $className = '\\app\\designer\\library\\database\\'.ucfirst($config['driver']);

        try{
            $obj = new $className();
            $obj->setDb($db);
            $list = $obj->getTableList();
            return $list;
        }catch(\Exception $e){
            throw new \Exception($e->getMessage());
        }
    }

    public function onSyncTable(){
        $name = $this->post('name',$this->check()->required());
        $list = $this->post('list',$this->check()->required());
        $db = Cubox::app($this->app->project($this->getApp())->toArray())->db($name);
        $config = $db->getConfig();
        $driver =  $config['driver'];
        $className = '\\app\\designer\\library\\database\\'.ucfirst($config['driver']);
        if (class_exists($className)){
            $_db = new $className();
            $_db->setDb($db);
            
            foreach($list as $key=>$model){
                $filePath = ROOT.DS.APP.DS.$this->getApp().DS.'_setup'.DS.'model'.DS.$model['name'].DS;
                $sql = $_db->getCreateTableSQL($model['table']);
                if (!is_dir($filePath)) mkdir($filePath,0777,true);
                file_put_contents($filePath.$driver.'.sql',$sql);
            }

            return ;
        }else{
            throw new \Exception('数据助手不存在');
        }
    }
    

    public function onConfigList(){
        $list =  $this->getConfigParam();

        $re =  [];
        $default = false;
        if (is_array($list)){
            foreach ($list as $key=>$value){
                $item['label'] = $value;
                $item['value'] = $key;
                if (strpos('默认',$value)!==false){
                    $item['default'] = true;
                    $default = true;
                }else{
                    $item['default'] = false;
                }

                $re [] = $item;
            }
        }

        if (!$default && count($re)>0) $re[0]['default'] = true;

        return $re;
    }

    public function onTableField(){
        $config = $this->post('config',$this->check()->required());
        $table =   $this->post('table',$this->check()->required());
        $db = Cubox::app($this->app->project($this->getApp())->toArray())->db($config);

        $name  = $db->getConfig()['driver'];

        $className = '\\app\\designer\\library\\database\\'.ucfirst($name);

        try{
            $obj = new $className();
            $obj->setDb($db);
            $field = $obj->getTableField($table);        
            return $field;
        }catch(\Exception $e){
            throw new \Exception($e->getMessage());
        }

    }

    public function onAddModel(){
        $data['config'] = $this->post('config',$this->check()->required());
        $data['table'] =   $this->post('table',$this->check()->required());
        $data['comment'] =  $this->post('comment');
        $model = $this->post('model',$this->check()->required());


        $app = $this->getApp();

        $project = $this->app->project($app);

        if ($project->model && array_key_exists($model,$project->model)){
            throw new \Exception('模型名称重复');
        }
        $list = $project->model;
        $list[$model] = $data;
        $project->model = $list;
        $project->save();
        return ;
    }

    public function onModelEdit(){
        $data['config'] = $this->post('config',$this->check()->required());
        $data['table'] =   $this->post('table',$this->check()->required());
        $data['key'] = $this->post('key',$this->check()->required());
        $data['comment'] =  $this->post('comment');
        $name = $this->post('name',$this->check()->required());
        $app = $this->getApp();

        $project = $this->app->project($app);
        $list = [];
        if ($project->model){
            $list = $project->model;
            if (array_key_exists($name,$project->model)){
                $data  = array_merge($list[$name] ,$data); 
            }
        }

        $list[$name] = $data;
        $project->model = $list;
        $project->save();
        return ;
    }

    public function onDelModel(){
        $name = $this->post('name',$this->check()->required());

        $project = $this->app->project($this->getApp());

        $list = $project->model;
        unset($list[$name]);
        $project->model = $list;
        $project->save();
        return ;
    }


    public function onUpdate(){
        $name = $this->getApp();

        $project = $this->app->project($name);
        
        $table =  $project->model;

        $modelPath = ROOT.DS.APP.DS.$name.DS.'model';
        
        $list  = [];
        if ($table){
            foreach ($table as $key => $value) {
                $table[$key]['file'] = file_exists($modelPath.DS.$key.'.php'); 
            }
        }

        $project->model =  $table;
        $project->save();
        
        return $list;
    }


    public function onAddFile(){
        $name = $this->post('name',$this->check()->required());

        $app = $this->getApp();

        $project = $this->app->project($app);
        $table =  $project->model;
        $data = [];
        
        if ($project->model == null || !isset($project->model[$name])){
            throw new \Exception('模型不存在');
        }

        $data = $project->model[$name];

        $filePath = ROOT.DS.APP.DS.$this->getApp().DS.'model';

        if (!is_dir($filePath)) mkdir($filePath,0777,true);

        $filePath.= DS.$name.'.php';
        if (!file_exists($filePath)) {
            $data['modelName'] =  $name;
            $content = $this->app->getExpContent($app,'Model',$data);
            file_put_contents($filePath,$content);


            $table[$name]['file'] = true; 
            $project->model = $table;
            $project->save();
            return true;
        }else{
            throw new \Exception('文件已存在');
        }
    }

    public function onBackUpList(){
        $filePath = ROOT.DS.APP.DS.$this->getApp().DS.'_setup'.DS.'database';
        $list  = [];
        $default = [];
        if (file_exists($filePath)){
            foreach (scandir($filePath) as $key => $value) {
                if ($value=='.' || $value=='..') continue;
                
                $path = $filePath.DS.$value;
                 if (is_dir($path)){

                    $fileList =  glob($filePath.DS.$value.DS.'*.sql');
                    $files = [];
                    foreach($fileList as $val) $files[] = pathinfo($val,PATHINFO_BASENAME); 

                    $list[] = [
                        'config' => $value,
                        'files' => $files
                    ];
                }else{
                    if (pathinfo($value,PATHINFO_EXTENSION)=='sql'){
                        $default[] = $value;
                    }
                }                
            }
        }

        //list 前面插入 default
       array_unshift($list,['config'=>'default','files'=>$default]);
       return $list;
    }

    public function onGetCreateSQL(){
        $modelName =  $this->post('modelName',$this->check()->required());
        
        $designerPath = ROOT.DS.APP.DS.$this->getApp().DS.'_setup'.DS.'config.php';
        $driverList  = [];
        if (file_exists($designerPath)){
            $designer = new Data($designerPath);
            $designer->read();
            $driverList  = $designer->driverList;
        }

        if (count( $driverList)==0){
            throw new \Exception('需要添加支持的数据库类型');
        }

        //获取默认数据库配置
       


        $filePath = ROOT.DS.APP.DS.$this->getApp().DS.'_setup'.DS.'model'.DS.$modelName.DS;

        $list  = [];

        //获取全部驱动
        if (is_array($driverList)){
            foreach($driverList as $driver){
            
                $content = '';
                if (file_exists($filePath.$driver.'.sql')){
                    $content = file_get_contents($filePath.$driver.'.sql');
                }

                $list[] = [
                    'driver' => $driver,
                    'content' => $content,
                    'config' => $this->getConfigParam($driver)
                ];
            }
        }
        
        return $list;

    }



    private function getConfigParam($driver = ''){
        static $configFile;
        $list  = [];

       
        if (!$configFile){
            $configFiles = [];
            $appConfigPath  = ROOT.DS.CONFIG.DS.$this->getApp().DS.'database.php';
            if (file_exists($appConfigPath)){
                $appConfig= new Data($appConfigPath);
                $configFile = $appConfig->toArray(); 
            }else{
                $configFile = Cubox::config('database')->toArray();
            }
        }
 
        

        if (isset($configFile['default'])){
            $default =  $configFile['default'];

            if (isset($configFile[$default])){
                $config = $configFile[$default];
                if ($driver=='' || $config['driver']==$driver){
                    $className ='\\cubox\\database\\'.ucfirst($config['driver']);
                    if (class_exists($className)) $list[$default] ='[默认]' . $default .'-' . $className::frontTitle( $config);
                    unset($configFile[$default]);
                }
            }
        }
 
        foreach($configFile as $name => $config){
            if (is_array($config) && isset($config['driver'])){
                if ($driver=='' || $config['driver']==$driver){
                    $className ='\\cubox\\database\\'.ucfirst($config['driver']);
                    if (class_exists($className)) $list[$name] = $name .'-' . $className::frontTitle($config);
                }
            }
        }
       
        return $list;
    }

    public function onSaveCreateSQL(){
        $sql = $this->post('sql');
        $modelName =  $this->post('modelName',$this->check()->required());
        $designerPath =ROOT.DS.APP.DS.$this->getApp().DS.'_setup'.DS.'config.php';
        $driverList  = [];
        if (file_exists($designerPath)){
            $designer = new Data($designerPath);
            $designer->read();
            $driverList  = $designer->driverList;
        }

        foreach ($driverList as $driver){
            $filePath = ROOT.DS.APP.DS.$this->getApp().DS.'_setup'.DS.'model'.DS.$modelName.DS;
            
            if (!file_exists($filePath)) mkdir($filePath, 0777, true);


            if (isset($sql[$driver]) && !empty($sql[$driver])){
                $content = $sql[$driver];
                file_put_contents($filePath.$driver.'.sql',$content);
            }
            
        }

        return true;
    }

    public function onGetCreateSQLText(){
        $modelName =  $this->post('modelName',$this->check()->required());
        $database =  $this->post('database',$this->check()->required());

        $name = $this->getApp();
        $project = $this->app->project($name);
      

        if ($project->exists('model') && $project->model[$modelName]){
            $model = $project->model[$modelName];
            $appConfigPath  = ROOT.DS.CONFIG.DS.$this->getApp().DS.'database.php';
            if (file_exists($appConfigPath)){
                $config = new Data($appConfigPath);
            }else{
                $config = Cubox::config('database');
            }
            

            if ($config->exists($database)){

                $db = Cubox::db($database,$config);

                $className = '\\app\\designer\\library\\database\\'.ucfirst($db->getConfig()['driver']);

                if (class_exists($className)){
                    $_db = new $className();
                    $_db->setDb($db);
                    return ['sql'=>$_db->getCreateTableSQL($model['table'])];

                }else{
                    throw new \Exception('数据助手不存在');
                }

            }else{
                throw new \Exception('数据库配置不存在');
            }

        }else{
            throw new \Exception('模型不存在');
        }
    }

}
